import mx.utils.Delegate;

import gugga.application.ApplicationController;
import gugga.application.NavigationManager;
import gugga.application.Section;
import gugga.commands.CommandManager;
import gugga.common.ITask;
import gugga.navigation.DropDownMenuItem;
import gugga.navigation.MenuNavigation;
import gugga.navigation.NavigationButton;
import gugga.sequence.ExecuteMethodTask;
import gugga.sequence.TaskSequence;

import siteWithSubSections.AboutSection;


/**
 * @author bony
 */
class siteWithSubSections.Application 
	extends ApplicationController

{
	// List all the application fields here. 
	private var mMainNavigation:MenuNavigation;
	
	private var mAboutButton:NavigationButton;
	private var mWhyButton:NavigationButton;
	private var mContactButton:NavigationButton;
	
	private var mAboutSection:AboutSection;
	private var mWhySection:Section;
	private var mContactSection:Section;

	private var mUndo:NavigationButton;
	private var mRedo:NavigationButton;
	
	// constructor	
	public function Application() 
	{
		// The constructor of the super class must be called.
		super();
		
		// The function getComponent creates a mapping between the instances on the scene and
		// the member variables of the Application class.
		mMainNavigation = getComponent("PrimaryNavigation");
		
		mAboutSection = getComponent("AboutSection");	
		mWhySection = getComponent("WhySection");	
		mContactSection = getComponent("ContactSection");	

		mUndo = getComponent("btnUndo");	
		mRedo = getComponent("btnRedo");	
		
		// Register instance of Application in the _global object, which is globally visible.
		// This allows external content to access application without using of singleton pattern. 
		_global["ApplicationController"] = this;
	}
	
	// All Objects instantiated inside the Application inherit UIComponentEx except macromedia components.
	// This function is required because we have to make sure that 
	// all objects inside the Application are associated with their respective classes and are avaialable and ready to work.
	// All sections are phisically nested inside the main Application and their initialization is not immediate.
	// Before execution of that function you cannot call any event related methods or mixin related methods of the objects.
	
	public function initUI()
	{
		// The constructor of the super class must be called.
		super.initUI();
		
		// Set initial state of undo /redo controls. 
		updateUndoState();
		
		// The button mUndo listens to the event click and executes the method onUndo.
		mUndo.addEventListener("click",Delegate.create(this, onUndo));
		// The button mRedo listens to the event click and executes the method onRedo.
		mRedo.addEventListener("click",Delegate.create(this, onRedo));
		
		// Command manager is responsible for keeping track of all reversible actions done within the system. 
		// We add Event listener to its event "commandBufferContentChanged" in order to update the state of the 
		// buttons redo and undo after every command. 
		CommandManager.Instance.addEventListener("commandBufferContentChanged",Delegate.create(this, updateUndoState));
		
		// Configure main navigation.
		configureMenu();
		
		// Register all the sections in the application.
		registerSections();
			
		// Open default section.				
		// Set navigation state. Should be set only the first time.
		// Add that tasks in the initializing Sequence.
		var openDefaultSectionTask:ITask = ExecuteMethodTask.create(this,this.navigateTo, ["About"]);		var startNavigationsTask:ITask = ExecuteMethodTask.create(NavigationManager.Instance, NavigationManager.Instance.startNavigations);
		
		// Initialization sequence
		var initializingSequence: TaskSequence = new TaskSequence();	
			
		// We have to include the default sections controller Initializing Sequence
		// in order to keep the class functional. 
		initializingSequence.addTask(mSectionsControllerInitializingSequence);		initializingSequence.addTask(startNavigationsTask);
		initializingSequence.addTask(openDefaultSectionTask);		this.registerInitializingTask(initializingSequence);
					
		// Trigger initializing sequence.
		initialize();
		
		// Activating sequence		
		// Using default activating sequence.
		
		// Open sequence		
		// Using default open sequence.
		
		// Close sequence		
		// Using default close sequence.    
	}
	
	public function configureMenu()
	{
		// List all items used for navigation - each one must have it's own uniqueID.		 
		// Navigation is using commands to take benefit of their reversibility. 
		mMainNavigation.registerChildSubItem("btnAbout", "About", "About");
		mMainNavigation.registerChildSubItem("btnWhy", "Why", "Why");
		
		// Realization of drop-down menu. 
		var menuDropDownContacts:DropDownMenuItem = 
			DropDownMenuItem(mMainNavigation.registerChildSubItem("dropDownContacts", "Contact", "Contact"));
			
		menuDropDownContacts.registerChildTitleButton("btnContact");

		menuDropDownContacts.registerChildSubItem("btnInfo", "Info", "Contact.Info");
		menuDropDownContacts.registerChildSubItem("btnInterest", "Interest", "Contact.Interest");

		NavigationManager.Instance.registerNavigation(mMainNavigation, "MainNavigation");	
	}
	
	public function registerSections()
	{
		registerChildSection("AboutSection","About","About");
		registerChildSection("WhySection","Why","Why");

		// This section contains 2 subsections - it acts as section controller. 
		// Subsections are registered in class file of container section. 
		// ContactSection class must extend SectionControler class. 
		registerChildSection("ContactSection","Contact","Contact");
	}
				
	// Determine state of undo and redo buttons depending of command history state.
	private function updateUndoState() : Void 
	{		
		mUndo.Enabled = CommandManager.Instance.hasUndoableActions();
		mRedo.Enabled = CommandManager.Instance.hasRedoableActions();		
	}

	private function onUndo() : Void 
	{
		CommandManager.Instance.undo();
	}
	
	private function onRedo() : Void 
	{
		CommandManager.Instance.redo();	
	}

}